from ast import Param
import hashlib
import hmac
import json
import requests.auth
import time
import urllib.parse
import sys
import base64
import datetime

from coin.exchange.base.kr_rest.auth_base import AuthKey
from coin2.api_client.common import (SyncQueryer)


class KucoinAuth(requests.auth.AuthBase):
  def __init__(self, key):
    self._key = AuthKey.from_file(key)
    self._json_key = {}
    with open(key) as f:
      self._json_key = json.load(f)

  def _gen_signature(self, now, method, endpoint, body):
    str_to_sign = str(now) + method + endpoint #+ body
    if body is not None:
       str_to_sign = str_to_sign + body.decode()
    signature = base64.b64encode(hmac.new(self._key.secret_key_bytes, str_to_sign.encode('utf-8'), hashlib.sha256).digest())
    return signature

  def __call__(self, req: requests.PreparedRequest):
    request = urllib.parse.urlparse(req.url)
    endpoint = request.path
    if request.query != "":
      endpoint = request.path + "?" + request.query
    now = int(time.time() * 1000)
    signature = self._gen_signature(now, req.method, endpoint, req.body)

    passphrase = base64.b64encode(hmac.new(self._key.secret_key_bytes, self._json_key["passphrase"].encode('utf-8'), hashlib.sha256).digest())
    headers = {
      "KC-API-SIGN": signature,
      "KC-API-TIMESTAMP": str(now),
      "KC-API-KEY": self._key.api_key,
      "KC-API-PASSPHRASE": passphrase,
      "KC-API-KEY-VERSION": "2"
    }

    req.headers.update(headers)
    return req


class KucoinPrivateClient():
  def __init__(self, key, mea:str):
    self._key = key
    self._auth = KucoinAuth(key)
    self._url = 'https://api.kucoin.com/'
    self._query = SyncQueryer(api_host=self._url, auth=self._auth)

  def get_balance(self, account_type: str):
    method = "GET"
    path = "/api/v1/accounts"
    params = {
        "type": account_type,
    }
  
    response = self._query.query(method=method, path=path, params=params)
    return response

  def get_open_order(self, symbol: str):
    method = "GET"
    #path = "/api/v1/orders"
    #params = {"status": "active"}
    path = "/api/v1/hf/orders/active"
    params = {"symbol": symbol}
    response = self._query.query(
        method=method, path=path, params=params)
    return response

  def cancel_order(self, id: str, symbol: str):
    method = "DELETE"
    #path = "/api/v1/orders/" + id
    path = "/api/v1/hf/orders/{0}?symbol={1}".format(id, symbol)
    response = self._query.query(
        method=method, path=path)
    return response

  def query_order_fills(self):
    method = "GET"
    path = "/api/v1/fills"
    params = {"pageSize":500}

    response = self._query.query(
        method=method, path=path, params=params)
    return response

  def deposits(self):
    method = "GET"
    path = "/api/v1/deposits"
    params = {}
    response = self._query.query(method=method, path=path, params = params)
    
    return response

  def withdrawals(self):
    method = "GET"
    path = "/api/v1/withdrawals"
    params = {}
  
    response = self._query.query(method=method, path=path, params=params)
    return response

  def inner_transfer(self, currency: str, from_account: str, to_account: str, amount: str):
    method = "POST"
    path = "/api/v2/accounts/inner-transfer"
    data = {
        "clientOid": str(int(time.time() * 1000000)),
        "currency": currency,
        "from": from_account,
        "to": to_account,
        "amount": amount,
    }

    response = self._query.query(method=method, path=path, json=data)
    #print(response.request.url)
    #print(response.request.headers)
    #print(response.request.body)
    return response

  def inner_transfer_all_by_account(self, from_account: str, to_account: str):
    response = self.get_balance(from_account)
    resp = response.json()
    data = resp['data']
    for bal in data:
      #print("{0} - {1} - {2} - {3}".format(bal['currency'], from_account, to_account, bal['balance']))
      self.inner_transfer(bal['currency'], from_account, to_account, bal['balance'])
    response = self.get_balance(to_account)
    return response

  def cancel_all_orders_norm(self):
    method = "GET"
    path = "/api/v1/orders"
    params = {
        "status": "active",
    }
    response = self._query.query(method=method, path=path, params=params)
    resp = response.json()
    data = resp['data']
    for order in data['items']:
      path = "/api/v1/orders/" + order['id']
      response = self._query.query(method='DELETE', path=path)
    return response


class KucoinFuturesPrivateClient():
  def __init__(self, key):
    self._key = key
    self._auth = KucoinAuth(key)
    self._url = 'https://api-futures.kucoin.com/'
    self._query = SyncQueryer(api_host=self._url, auth=self._auth)

  def get_balance(self, currency: str):
    method = "GET"
    path = "/api/v1/account-overview"
    params = {
        "currency": currency,
    }

    response = self._query.query(method=method, path=path, params=params)
    return response


if __name__ == "__main__":
  key = sys.argv[1]
  #config = {}
  # config["key_path"] = key
  # config["mea"] = "Spot.Kucoin.v1"
  # order, resp = detecotor_open_order(config)
  #print(json.dumps(order, indent=2))

  kucoin = KucoinFuturesPrivateClient(key)
  response = kucoin.get_balance("USDT")

  #kucoin = KucoinPrivateClient(key)
  #response = kucoin.withdrawals()
  #response = kucoin.get_open_order("BTC-USDT")
  #response = kucoin.cancel_all_orders_norm()
  #response = kucoin.inner_transfer("BTC", "trade_hf", "trade", "0.0002")
  #response = kucoin.inner_transfer_all_by_account("trade", "trade_hf")
  print(json.dumps(response.json(), indent=2))

